import { IMenu } from '@/types/api';
import { CustomRouteObject } from '@/types/react-router-dom';

/**
 * 将数字或字符串格式化为人民币货币格式的字符串，例如：¥1,234.56
 *
 * @param num 要格式化的数字，可以是数字类型或字符串类型
 * @returns 格式化后的字符串,并且带有货币符号以及千位分隔符
 */
export const formatMoney = (num?: number | string) => {
    if (!num) {
        return '¥0.00';
    }
    const number = parseFloat(num.toString());
    return number.toLocaleString('zh-CN', { style: 'currency', currency: 'CNY' });
};

/**
 * 将数字或字符串格式化为带有千位分隔符的字符串，例如：1,234.56
 *
 * @param num 要格式化的数字，可以是数字类型或字符串类型
 * @returns 格式化后的字符串，带有千位分隔符
 */
export const formatNum = (num?: number | string) => {
    if (!num) {
        return '0.00';
    }
    const str = num.toString();
    // 浮点
    if (str.indexOf('.') > -1) {
        return str.replace(/(\d)(?=(\d{3})+\.)/g, '$1,');
    }
    // 整数
    return str.replace(/(\d)(?=(\d{3})+$)/g, '$1,');
};

// 格式化日期
export const toLocalDate = (date?: Date | string, rule?: string) => {
    let curDate = new Date();

    if (date instanceof Date) {
        curDate = date;
    } else if (date) {
        curDate = new Date(date);
    }

    if (rule === 'yyyy-MM-dd') return curDate.toLocaleDateString().replaceAll('/', '-');
    if (rule === 'HH:mm:ss') return curDate.toLocaleTimeString().replaceAll('/', '-');

    return curDate.toLocaleString().replaceAll('/', '-');
};

// 格式化日期
export const formatDate = (date?: Date | string, rule?: string) => {
    let curDate = new Date();

    if (date instanceof Date) {
        curDate = date;
    } else if (date) {
        curDate = new Date(date);
    }

    let fmt = rule || 'yyyy-MM-dd HH:mm:ss';
    fmt = fmt.replace(/(y+)/, curDate.getFullYear().toString());
    type OType = {
        [key: string]: number;
    };
    const O: OType = {
        'M+': curDate.getMonth() + 1,
        'd+': curDate.getDate(),
        'H+': curDate.getHours(),
        'm+': curDate.getMinutes(),
        's+': curDate.getSeconds()
    };
    for (const k in O) {
        fmt = fmt.replace(new RegExp(`(${k})`), O[k] > 9 ? O[k].toString() : '0' + O[k].toString());
        // const val = O[k].toString();
        // fmt = fmt.replace(new RegExp(`(${k})`), ('00' + val).substring(val.length))
    }
    return fmt;
};

// 用户状态转换
export const formatState = (state: string) => {
    if (state === '1') return '在职';
    if (state === '2') return '试用期';
    if (state === '3') return '离职';
};

/**
 * 手机号加密
 * @example
 * 17611000011 => 176****0011
 */
export const formateMobile = (mobile?: number) => {
    if (!mobile) return '-';
    const phone = mobile.toString();
    return phone.replace(/(\d{3})\d*(\d{4})/, '$1****$2');
};

/**
 * 获取页面路径数组
 * @param list
 * @returns
 */
export const getMenuPath = (list: IMenu.MenuItem[]): string[] => {
    return list.reduce((result: string[], item: IMenu.MenuItem) => {
        // 末级菜单具有buttons属性
        return result.concat(
            // 如果当前项有children且没有buttons属性，则为中间节点，否则为末级菜单
            Array.isArray(item.children) && !item.buttons ? getMenuPath(item.children) : item.path || ''
        );
    }, []);
};

/**
 * 递归获取路由对象
 * @param path
 * @param routes
 * @returns
 */
export const searchRoute = (
    path: string,
    routes: (CustomRouteObject | IMenu.MenuItem)[] = []
): CustomRouteObject | IMenu.MenuItem | null => {
    // 遍历路由数组
    for (const item of routes) {
        // 如果当前路由的路径与传入路径匹配，则返回当前路由对象
        if (item.path === path) return item;

        // 如果当前路由有子路由
        if (item.children) {
            // 递归调用searchRoute函数，传入子路由数组和路径
            const result = searchRoute(path, item.children);
            // 如果找到了匹配的路由，则返回该路由对象
            if (result) return result;
        }
    }
    // 如果没有找到匹配的路由，则返回null
    return null;
};

/* 
[
	{
        path:'order',
        menuName: '订单管理',
        children:[ 
            { path:'/orderList', menuName: '订单列表' } 
			{ path:'/clusterList', menuName: '订单聚合' } 
        ]
    },
    {
        path:'system',
        menuName: '系统管理',
        children:[ 
            { path:'/userList', menuName: '用户列表' },
			{ path:'/menuList', menuName: '菜单列表' }  
        ]
    }
]
 */
/**
 * 递归查找树的路径
 */
/**
 * 在菜单树中查找指定路径的节点，并返回从根节点到目标节点的菜单名称列表
 *
 * @param tree 菜单树数组
 * @param pathname 需要查找的路径名称，例如：'/userList'
 * @param menuNameList 存储路径上每个节点的菜单名称的列表
 * @returns 从根节点到目标节点的菜单名称列表，如果未找到则返回空数组
 */
export const findTreeNode = (tree: IMenu.MenuItem[], pathname: string, menuNameList: string[]): string[] => {
    // 如果树为空，则返回一个空的路径列表
    if (!tree) return [];

    for (const item of tree) {
        // 将当前节点的菜单名称添加到路径列表中
        menuNameList.push(item.menuName);

        // 如果当前节点的路径与给定的路径名称匹配，则返回路径列表,终止递归
        if (item.path === pathname) return menuNameList;

        // 如果当前节点有子节点
        if (item.children?.length) {
            // 递归调用函数，传入子节点、路径名称和路径列表
            const list = findTreeNode(item.children, pathname, menuNameList);
            // 如果递归调用返回的路径列表不为空，则返回该列表
            if (list?.length) return list;
        }

        // 如果当前节点不匹配且没有子节点，则删除路径列表中的最后一个元素（即当前节点的菜单名称）
        menuNameList.pop(); // 删除末级未匹配
    }

    return [];
};
